Laro.register('VHome', function (La) {
    var pkg = this;
    console.log(VHome.config)
    this.initStage = function () {
        var canvas = document.getElementById('canvas');
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        this.canvas = canvas;
        this.stage = new CVS.$stage(canvas);
        this.ctx = this.stage.ctx;
        this.vpx = canvas.width/2;
        this.vpy = canvas.height/2;
        this.normalN = 100;
        this.normalBalls = [];
        this.angleX = 0.001;
        this.angleY = 0.001;

        this.zstep = 1;
        this.zflag = 1;
    }

    this.range = function (a, b) {
        return Math.floor(Math.random()*(b-a) + a);
    }

    this.tween = function (ball, t) {
        if (!ball.end) {
            var _x = ball.xpos, _y = ball.ypos, _z = ball.zpos;
            var _t = (+new Date) - ball.startAnimTime;
                ball.xpos = ball.f_xpos + (ball.t_xpos - ball.f_xpos)*Math.sin(Math.PI*_t/(2*t));
                ball.ypos = ball.f_ypos + (ball.t_ypos - ball.f_ypos)*Math.sin(Math.PI*_t/(2*t));
                ball.zpos = ball.f_zpos + (ball.t_zpos - ball.f_zpos)*Math.sin(Math.PI*_t/(2*t));

             if (_t >= t) {
                ball.end = true;
            }
        }
    }

    this.addNormalBalls = function (n) {
        var vpx = this.vpx, vpy = this.vpy, range = this.range, stage = this.stage,
            _this = this;
        if (n) {
            this.normalN = n;
        }
        for (var i=0; i< this.normalN; i++) {

            var ball = CVS.createPoint3D(this.stage.ctx, function () {
                var color = 'rgb('+range(0, 256)+', '+range(0, 256)+', '+range(0, 256)+')';
                this.xpos = range(-vpx, vpx);
                this.ypos = range(-vpy, vpy);
                this.zpos = range(-vpx, vpx);

                this.width = range(8, 15);
                this.w = this.width;
                this.draw = function () {
                    this.ctx.beginPath();
                    this.ctx.arc(0, 0, this.width/2, 0, Math.PI*2, true);
                    this.ctx.closePath();
                    this.ctx.fillStyle = color;
                    this.ctx.fill();
                }
            });
            ball.type = 'normal';
            ball.setVanishPoint(vpx, vpy);
            ball.setCenterPoint(0, 0, 0);
            stage.addChild(ball);
            this.normalBalls.push(ball);
        }
    }

    this.updateBalls = function (dt, name) {
        var balls = this.particleHash[name];
        for (var i = 0; i < balls.length; i ++) {
            var ball = balls[i];

            ball.zpos += VHome.zstep;

            ball.rotateX(this.angleX);
            ball.rotateY(this.angleY);
            var scale = ball.getScale(),
                pos = ball.getScreenXY();
            ball.width = Math.max(10*scale, 2);
            ball.x = pos.x;
            ball.y = pos.y;
        }
    };

    this.pushBalls = function (name) {
        var balls = this.particleHash[name];
        for (var i = 0; i < balls.length; i ++) {
            var ball = balls[i];
            VHome.stage.addChild(ball);
            ball.end = false;
            ball.width = ball.logoPos.width;
            ball.color = 'rgb('+ball.logoPos.r+', '+ball.logoPos.g+', '+ball.logoPos.b+')';
            ball.startAnimTime = (+ new Date);

        }
    }

    this.bindStage = function () {
        var _this = this;
        this.stage.addEventListener('mousemove', function (x, y) {
            _this.angleY = (x - _this.vpx) * .00001;
            _this.angleX = (y - _this.vpy) * .00001;
        })
    }

    this.initParticles = function () {
        var states = VHome.config.states;
        var state = null;
        this.particleHash = {
            'normal': this.normalBalls
        };
        for (var i = 0, l = states.length; i < l; i++) {
            state = states[i];
            this.particleHash[state.id] = this.getParticles(state.id, state.w, state.h, state.z);
            this[state.id + 'Particles'] = this.particleHash[state.id];
        };
    }
    this.getParticles = function (id, w, h, z) {
        if (z == undefined) { z = 0; }
        var image = document.getElementById(id);
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.ctx.drawImage(image, 0, 0, w, h, this.canvas.width/2-w/4, this.canvas.height/2-h/4, w/2, h/2);

        var imageData = this.ctx.getImageData(this.canvas.width/2-w/4, this.canvas.height/2-h/4, w/2, h/2);
        var ret = [];
        for (var x = 0; x < imageData.width; x ++) {
            for (var y = 0; y < imageData.height; y ++) {
                //var i = 4*(x * imageData.height + y);
                var i = 4*(y * imageData.width + x);
                if (imageData.data[i + 3] > 128) { // 半透以上就算
                    var r = imageData.data[i],
                        g = imageData.data[i + 1],
                        b = imageData.data[i + 2];
                    ret.push(new VHome.Particle(this.stage, this.canvas, id, w, h, x, y, z, r, g, b));
                }
            }
        }
        return ret;
    }

    this.Particle = function (stage, canvas, id, w, h, x, y, z, r, g, b) {
        this.canvas = canvas;

        var vpx = canvas.width/2,
            vpy = canvas.height/2,
            range = pkg.range;

        var ball =  CVS.createPoint3D(stage.ctx, function () {
            var color = 'rgb('+ range(200, 255) +', '+ range(200, 255) +', '+ range(200, 255) +')';
            var a = Math.PI * 2 * Math.random();
            var b = Math.PI * 2 * Math.random();
            var r = range(vpx, vpy);

            this.xpos = Math.sin(a) * Math.sin(b) * r;
            this.ypos = Math.cos(a) * Math.sin(b) * r;
            this.zpos = -Math.abs(Math.cos(b) * r);

            this.width = range(3, 15);
            this.color = color;
            this.draw = function () {
                this.ctx.beginPath();
                this.ctx.arc(0, 0, this.width/2, 0, Math.PI*2, true);
                this.ctx.closePath();
                this.ctx.fillStyle = this.color;
                this.ctx.fill();
            }
        });

        ball.logoPos = {
            x: (x-w/4)*20,
            y: (y-h/4)*20,
            z: 0,
            width: 10,
            r: r,
            g: g,
            b: b
        };
        ball.f_xpos = ball.xpos;
        ball.f_ypos = ball.ypos;
        ball.f_zpos = ball.zpos;
        ball.t_xpos = ball.logoPos.x;
        ball.t_ypos = ball.logoPos.y;
        ball.t_zpos = ball.logoPos.z;
        ball.startAnimTime = (+new Date);
        ball.end = true;
        ball.type = id;

        ball.setVanishPoint(canvas.width/2, canvas.height/2);
        ball.setCenterPoint(0, 0, z);

        ball.moveX = 1 - Math.random()*2;
        //stage.addChild(ball);

        return ball;
    }

    this.init = function () {
        this.initStage();
        this.bindStage();
        this.initParticles();
        //this.addNormalBalls();

        VHome.$fsm.init();
        VHome.$loop.init();
    }
});
